// 交互封装：统一处理 pointer 事件、坐标换算与消息发送
import Position from './Position'
import { KeyCodeControlMessage, TouchControlMessage, ScrollControlMessage } from './ControlMessage'

export default class InteractionHandler {
  constructor(options) {
    const {
      element,
      deviceWidth,
      deviceHeight,
      sendBuffer,
      enableDebug = false,
      enableWheel = false,
    } = options || {}

    if (!element) throw new Error('InteractionHandler requires element')
    if (typeof sendBuffer !== 'function') throw new Error('InteractionHandler requires sendBuffer function')

    this.element = element
    this.sendBuffer = sendBuffer
    this.position = new Position(element, deviceWidth || 720, deviceHeight || 1280)
    this.debug = !!enableDebug
    this.enableWheel = !!enableWheel
    this.activePointerId = null
    this.lastMoveAt = 0
    this.moveTimer = null

    this.bind()
  }

  setDeviceSize(w, h) {
    this.position.setDeviceSize(w, h)
  }

  bind() {
    const el = this.element
    el.style.touchAction = 'none'
    this.onPointerDown = (e) => {
      try { el.setPointerCapture && el.setPointerCapture(e.pointerId) } catch (_) {}
      e.preventDefault()
      const { x, y } = this.position.toDevicePoint(e.clientX, e.clientY)
      this.activePointerId = 0 // 与 ws-scrcpy 默认映射一致，首指从0开始
      const msg = new TouchControlMessage(0, this.activePointerId, x, y, this.position.deviceWidth, this.position.deviceHeight, 1.0, 1)
      this.sendBuffer(msg.toBuffer())
      if (this.debug) console.log('touch DOWN', x, y)
    }
    this.onPointerUp = (e) => {
      e.preventDefault()
      if (this.activePointerId == null) return
      const { x, y } = this.position.toDevicePoint(e.clientX, e.clientY)
      const msg = new TouchControlMessage(1, this.activePointerId, x, y, this.position.deviceWidth, this.position.deviceHeight, 0, 0)
      this.sendBuffer(msg.toBuffer())
      this.activePointerId = null
      if (this.debug) console.log('touch UP', x, y)
      try { el.releasePointerCapture && el.releasePointerCapture(e.pointerId) } catch (_) {}
    }
    this.onPointerMove = (e) => {
      if (this.activePointerId == null) return
      e.preventDefault()
      const now = performance.now()
      const due = () => {
        const { x, y } = this.position.toDevicePoint(e.clientX, e.clientY)
        const msg = new TouchControlMessage(2, this.activePointerId, x, y, this.position.deviceWidth, this.position.deviceHeight, 1.0, 1)
        this.sendBuffer(msg.toBuffer())
        if (this.debug) console.log('touch MOVE', x, y)
      }
      if (!this.lastMoveAt || now - this.lastMoveAt > 12) {
        this.lastMoveAt = now
        due()
      } else {
        clearTimeout(this.moveTimer)
        this.moveTimer = setTimeout(due, 12)
      }
    }
    this.onPointerCancel = (e) => {
      e.preventDefault()
      if (this.activePointerId == null) return
      const { x, y } = this.position.toDevicePoint(e.clientX, e.clientY)
      const msg = new TouchControlMessage(3, this.activePointerId, x, y, this.position.deviceWidth, this.position.deviceHeight, 0, 0)
      this.sendBuffer(msg.toBuffer())
      this.activePointerId = null
      if (this.debug) console.log('touch CANCEL', x, y)
    }

    el.addEventListener('pointerdown', this.onPointerDown)
    el.addEventListener('pointerup', this.onPointerUp)
    el.addEventListener('pointermove', this.onPointerMove)
    el.addEventListener('pointercancel', this.onPointerCancel)

    // 滚轮 -> Scroll 事件
    if (this.enableWheel) {
      this.onWheel = (e) => {
        try {
          e.preventDefault()
        } catch (_) {}
        const deltaX = (e.deltaX || 0) | 0
        const deltaY = (e.deltaY || 0) | 0
        const { x, y } = this.position.toDevicePoint(e.clientX, e.clientY)
        const msg = new ScrollControlMessage(x, y, this.position.deviceWidth, this.position.deviceHeight, deltaX, deltaY, 0)
        this.sendBuffer(msg.toBuffer())
        if (this.debug) console.log('wheel SCROLL', { x, y, deltaX, deltaY })
      }
      el.addEventListener('wheel', this.onWheel, { passive: false })
    }
  }

  unbind() {
    const el = this.element
    try { el.removeEventListener('pointerdown', this.onPointerDown) } catch (_) {}
    try { el.removeEventListener('pointerup', this.onPointerUp) } catch (_) {}
    try { el.removeEventListener('pointermove', this.onPointerMove) } catch (_) {}
    try { el.removeEventListener('pointercancel', this.onPointerCancel) } catch (_) {}
    if (this.enableWheel) {
      try { el.removeEventListener('wheel', this.onWheel) } catch (_) {}
    }
    clearTimeout(this.moveTimer)
  }

  // 系统键封装
  sendKeyDownUp(keycode) {
    const down = new KeyCodeControlMessage(0, keycode, 0, 0)
    const up = new KeyCodeControlMessage(1, keycode, 0, 0)
    this.sendBuffer(down.toBuffer())
    setTimeout(() => this.sendBuffer(up.toBuffer()), 10)
  }

  // 滚动封装（按像素/行转换由调用侧决定）
  sendScrollFromClient(clientX, clientY, deltaX, deltaY) {
    const { x, y } = this.position.toDevicePoint(clientX, clientY)
    const msg = new ScrollControlMessage(x, y, this.position.deviceWidth, this.position.deviceHeight, deltaX | 0, deltaY | 0, 0)
    this.sendBuffer(msg.toBuffer())
  }
}


